import 'dart:convert';
import 'package:injectable/injectable.dart';
import 'package:vista/shared/models/group_message.dart';
import 'package:vista/shared/models/group_snapshot.dart';
import 'package:vista/shared/models/user_frame.dart';
import 'package:vista/shared/services/storage_service.dart';
import 'package:vista/shared/services/auth_focus.dart';

/// 圈子画廊
/// 处理圈子的创建、加入、消息发送，如摄影画廊般管理圈子
@lazySingleton
class CircleGallery {
  final StorageService _storageService;
  final AuthFocus _authFocus;
  static const String _groupsKey = 'groups';
  static const String _membersPrefix = 'group_members_';
  static const String _messagesPrefix = 'group_messages_';
  static const String _isInitializedKey = 'groups_initialized';

  CircleGallery(this._storageService, this._authFocus);

  /// 初始化默认圈子数据
  /// 创建3个默认圈子并为每个圈子创建一些成员和消息
  Future<void> initializeDefaultGroups() async {
    final isInitialized = await _storageService.retrieveBool(_isInitializedKey);
    if (isInitialized == true) {
      return; // 已经初始化过了
    }

    final users = await _authFocus.getUsers();
    if (users.isEmpty) {
      return;
    }

    final now = DateTime.now();
    final defaultGroups = <GroupSnapshot>[];
    final defaultMembers = <String, List<String>>{};
    final defaultMessages = <GroupMessage>[];

    // 创建3个默认圈子
    final groupTitles = [
      'Y2K style group',
      'Characters group',
      'Scenery style group',
    ];

    // 找到 admin 用户
    UserFrame? adminUser;
    try {
      adminUser = await _authFocus.findUserByAccount('admin');
    } catch (e) {
      adminUser = null;
    }

    // 获取除 admin 外的其他用户
    final otherUsers =
        adminUser != null
            ? users.where((u) => u.id != adminUser!.id).toList()
            : users;

    for (int i = 0; i < groupTitles.length; i++) {
      final groupId = 'group_${now.millisecondsSinceEpoch}_$i';

      defaultGroups.add(
        GroupSnapshot(
          id: groupId,
          title: groupTitles[i],
          image: 'assets/images/group${(i % 10) + 1}.png',
          createdAt: now.subtract(Duration(days: i + 5)),
        ),
      );

      // 为每个圈子添加成员
      final memberIds = <String>[];

      // 第一个圈子：admin + 其他用户（4个）
      if (i == 0) {
        if (adminUser != null) {
          memberIds.add(adminUser.id);
        }
        // 从其他用户中取4个
        final otherMembers = otherUsers.take(4).toList();
        memberIds.addAll(otherMembers.map((u) => u.id));
      } else {
        // 其他圈子：只从其他用户中取（5-7个成员）
        final members = otherUsers.take(4 + i).toList();
        memberIds.addAll(members.map((u) => u.id));
      }

      defaultMembers[groupId] = memberIds;

      // 获取成员用户对象用于创建消息
      final members = users.where((u) => memberIds.contains(u.id)).toList();

      // 为每个圈子创建默认消息
      final messages = _getGroupMessages(i, groupId, members, now);
      defaultMessages.addAll(messages);
    }

    // 保存所有数据
    await _saveGroups(defaultGroups);
    await _saveMembers(defaultMembers);
    await _saveMessages(defaultMessages);
    await _storageService.persistBool(_isInitializedKey, true);
  }

  /// 获取圈子消息内容
  List<GroupMessage> _getGroupMessages(
    int groupIndex,
    String groupId,
    List<UserFrame> members,
    DateTime now,
  ) {
    final messages = <GroupMessage>[];

    // 根据圈子类型生成不同的消息内容
    final messageContents = _getMessageContents(groupIndex);

    // 为每个圈子创建8-12条消息
    final messageCount = 8 + groupIndex * 2;
    for (int i = 0; i < messageCount && i < members.length; i++) {
      final member = members[i % members.length];
      final contentIndex = i % messageContents.length;

      messages.add(
        GroupMessage(
          id: 'group_msg_${now.millisecondsSinceEpoch}_${groupId}_$i',
          groupId: groupId,
          userId: member.id,
          content: messageContents[contentIndex],
          timestamp: now.subtract(
            Duration(
              days: groupIndex + 5,
              hours: messageCount - i,
              minutes: i * 5,
            ),
          ),
        ),
      );
    }

    return messages;
  }

  /// 获取消息内容
  List<String> _getMessageContents(int groupIndex) {
    final contents = [
      // Y2K style group
      [
        'Love the Y2K aesthetic! So nostalgic!',
        'Anyone want to share some Y2K style photos?',
        'The colors in this group are amazing!',
        'Y2K fashion is making a comeback!',
        'Great inspiration here!',
        'Let\'s keep this aesthetic alive!',
        'Beautiful vintage vibes!',
        'Y2K never goes out of style!',
      ],
      // Characters group
      [
        'Character photography is so creative!',
        'Love seeing everyone\'s unique characters!',
        'Great composition in these shots!',
        'Characters really bring photos to life!',
        'Amazing storytelling through characters!',
        'Keep sharing your creative work!',
        'These characters are fascinating!',
        'Character photography is an art form!',
      ],
      // Scenery style group
      [
        'Nature photography is breathtaking!',
        'These landscapes are stunning!',
        'Love the natural lighting!',
        'Scenery photography captures the beauty of nature!',
        'Amazing perspectives on these landscapes!',
        'Nature never fails to inspire!',
        'Beautiful scenery shots everyone!',
        'Keep exploring and capturing nature!',
      ],
    ];

    return contents[groupIndex % contents.length];
  }

  /// 保存圈子列表
  Future<void> _saveGroups(List<GroupSnapshot> groups) async {
    final groupsJson = groups.map((group) => group.toJson()).toList();
    final groupsString = jsonEncode(groupsJson);
    await _storageService.persistString(_groupsKey, groupsString);
  }

  /// 获取所有圈子
  Future<List<GroupSnapshot>> getAllGroups() async {
    final groupsString = await _storageService.retrieveString(_groupsKey);
    if (groupsString == null) {
      return [];
    }

    try {
      final List<dynamic> groupsJson = jsonDecode(groupsString);
      return groupsJson
          .map((json) => GroupSnapshot.fromJson(json as Map<String, dynamic>))
          .toList()
        ..sort((a, b) => b.createdAt.compareTo(a.createdAt));
    } catch (e) {
      return [];
    }
  }

  /// 根据ID获取圈子
  Future<GroupSnapshot?> getGroupById(String groupId) async {
    final groups = await getAllGroups();
    try {
      return groups.firstWhere((group) => group.id == groupId);
    } catch (e) {
      return null;
    }
  }

  /// 创建圈子
  Future<GroupSnapshot> createGroup({
    required String title,
    required String image,
  }) async {
    final group = GroupSnapshot(
      id: 'group_${DateTime.now().millisecondsSinceEpoch}',
      title: title,
      image: image,
      createdAt: DateTime.now(),
    );

    final allGroups = await getAllGroups();
    allGroups.insert(0, group);
    await _saveGroups(allGroups);

    return group;
  }

  /// 保存成员列表
  Future<void> _saveMembers(Map<String, List<String>> members) async {
    for (final entry in members.entries) {
      final key = '$_membersPrefix${entry.key}';
      await _storageService.persistStringList(key, entry.value);
    }
  }

  /// 获取圈子的成员列表
  Future<List<String>> getGroupMembers(String groupId) async {
    final key = '$_membersPrefix$groupId';
    final members = await _storageService.retrieveStringList(key);
    return members ?? [];
  }

  /// 获取圈子的成员数量
  Future<int> getMemberCount(String groupId) async {
    final members = await getGroupMembers(groupId);
    return members.length;
  }

  /// 检查用户是否已加入圈子
  Future<bool> isMember(String groupId, String userId) async {
    final members = await getGroupMembers(groupId);
    return members.contains(userId);
  }

  /// 加入圈子
  Future<void> joinGroup(String groupId, String userId) async {
    if (await isMember(groupId, userId)) {
      return; // 已经加入了
    }

    final members = await getGroupMembers(groupId);
    members.add(userId);

    final key = '$_membersPrefix$groupId';
    await _storageService.persistStringList(key, members);
  }

  /// 退出圈子
  Future<void> leaveGroup(String groupId, String userId) async {
    if (!await isMember(groupId, userId)) {
      return; // 本来就不是成员
    }

    final members = await getGroupMembers(groupId);
    members.remove(userId);

    final key = '$_membersPrefix$groupId';
    if (members.isEmpty) {
      await _storageService.removeKey(key);
    } else {
      await _storageService.persistStringList(key, members);
    }
  }

  /// 获取用户加入的圈子列表
  Future<List<String>> getUserGroups(String userId) async {
    final allGroups = await getAllGroups();
    final userGroups = <String>[];

    for (final group in allGroups) {
      if (await isMember(group.id, userId)) {
        userGroups.add(group.id);
      }
    }

    return userGroups;
  }

  /// 保存消息列表
  Future<void> _saveMessages(List<GroupMessage> messages) async {
    final messagesByGroup = <String, List<GroupMessage>>{};
    for (final message in messages) {
      messagesByGroup.putIfAbsent(message.groupId, () => []).add(message);
    }

    for (final entry in messagesByGroup.entries) {
      final key = '$_messagesPrefix${entry.key}';
      final messagesJson = entry.value.map((msg) => msg.toJson()).toList();
      final messagesString = jsonEncode(messagesJson);
      await _storageService.persistString(key, messagesString);
    }
  }

  /// 获取圈子的消息列表
  Future<List<GroupMessage>> getGroupMessages(String groupId) async {
    final key = '$_messagesPrefix$groupId';
    final messagesString = await _storageService.retrieveString(key);
    if (messagesString == null) {
      return [];
    }

    try {
      final List<dynamic> messagesJson = jsonDecode(messagesString);
      return messagesJson
          .map((json) => GroupMessage.fromJson(json as Map<String, dynamic>))
          .toList()
        ..sort((a, b) => a.timestamp.compareTo(b.timestamp));
    } catch (e) {
      return [];
    }
  }

  /// 获取圈子的消息数量
  Future<int> getMessageCount(String groupId) async {
    final messages = await getGroupMessages(groupId);
    return messages.length;
  }

  /// 发送消息到圈子
  Future<GroupMessage> sendMessage({
    required String groupId,
    required String userId,
    required String content,
  }) async {
    // 检查用户是否是圈子成员
    if (!await isMember(groupId, userId)) {
      throw Exception('User must be a member of the group to send messages');
    }

    final message = GroupMessage(
      id: 'group_msg_${DateTime.now().millisecondsSinceEpoch}_$groupId',
      groupId: groupId,
      userId: userId,
      content: content,
      timestamp: DateTime.now(),
    );

    final messages = await getGroupMessages(groupId);
    messages.add(message);
    await _saveGroupMessages(groupId, messages);

    return message;
  }

  /// 保存圈子的消息列表
  Future<void> _saveGroupMessages(
    String groupId,
    List<GroupMessage> messages,
  ) async {
    final key = '$_messagesPrefix$groupId';
    final messagesJson = messages.map((msg) => msg.toJson()).toList();
    final messagesString = jsonEncode(messagesJson);
    await _storageService.persistString(key, messagesString);
  }

  /// 删除消息
  Future<void> deleteMessage(String messageId, String groupId) async {
    final messages = await getGroupMessages(groupId);
    messages.removeWhere((message) => message.id == messageId);
    await _saveGroupMessages(groupId, messages);
  }

  /// 删除群组的所有消息
  Future<void> deleteAllGroupMessages(String groupId) async {
    final key = '$_messagesPrefix$groupId';
    await _storageService.removeKey(key);
  }
}
